#include <iostream>
#include <cstdlib>
#include <map>
#include <set>
#include <vector>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdio>

using namespace std;

const int maxN = 5000000 + 100;

vector<int> edge_list[maxN];
int next_ep[maxN];
int inCount[maxN];
bool visited[maxN];
bool inQueue[maxN];
int timemark[maxN];

int nCount, nEasy, nHard;
int timeflag;
set<int> cand;

void init()
{
	for (int i = 0; i < nCount; ++i)
	{
		edge_list[i].clear();
		next_ep[i] = -1;
		inCount[i] = 0;
		visited[i] = 0;
		timemark[i] = 0;
		inQueue[i] = false;
	}
	
	timeflag = 0;
}

int top;
pair<int, int> stack[maxN];

bool DFS(int st, int base)
{
	++timeflag;
	
	top = 1;
	stack[0] = make_pair(st, base);
	while (top)
	{
		pair<int, int> &head = stack[top - 1];
		int u = head.first;
		//printf("top = %d, head.second = %d, edge_list[u].size() = %d\n", top, head.second, edge_list[u].size());
		if (head.second >= edge_list[u].size())
		{
			--top;
			continue;
		}
		
		int v = edge_list[u][head.second];
		head.second ++;
		
		if (visited[v] && v != st)
		{
			stack[top++] = make_pair(v, 0);
			return true;
		}

		if (!visited[v] && timemark[v] < timeflag)
		{
			timemark[v] = timeflag;
			stack[top++] = make_pair(v, 0);
		}
	}
	
	return false;
}

bool find_solution()
{
	bool dup = (nHard == nEasy);
	if (dup)
	{
		printf("NO\n");
		return 0;
		for (int i = 0; i < edge_list[nEasy].size(); ++i)
		{
			int u = edge_list[nEasy][i];
			edge_list[nCount].push_back(u);
			edge_list[u].push_back(nCount);
		}
		
		nHard = nCount;
		++nCount;
	}
	
	visited[nHard] = visited[nEasy] = true;
	
	static int queue[maxN];
	int open = 0;
	cand.clear();
	cand.insert(nEasy);
	
	for ( ; cand.size() > 0; )
	{
		int u = *cand.begin();
		inQueue[u] = true;
		cand.erase(u);
		queue[open++] = u;
		if (u == nHard)
			break;
			
//		printf("working on %d, next_ep = %d\n", u, next_ep[u]);
		
		if (next_ep[u] >= 0)
		{
			int v = next_ep[u];
			if (--inCount[v] == 0 && !inQueue[v])
			    cand.insert(v);
		}
		
		int base = 0;
		
		while (DFS(u, base))
		{
//			printf("DFS: %d %d, nBase = %d\n", u, base, stack[0].second);
//			for (int i = 0; i < top; ++i) printf("%d ", stack[i].first); printf("\n");
			base = stack[0].second;
			for (int i = 1; i < top - 1; ++i)
			{
				int u = stack[i].first;
				int v = stack[i + 1].first;
				++inCount[v];
				cand.erase(v);
				next_ep[u] = v;
				visited[u] = true;
				visited[v] = true;
			}
//			printf("state: ");
//			for (int i = 0; i < nCount; ++i) printf("%d ", inCount[i]); printf("\n");
//			for (int i = 0; i < nCount; ++i) printf("%d ", inQueue[i]); printf("\n");

			int w = stack[1].first;
			if (inCount[w] == 0 && inQueue[w] == false)
			{
				cand.insert(w);
			    //inQueue[w] = true;
			}
		}
	}
	
	for (int i = 0; i < edge_list[nHard].size(); ++i)
	{
		int u = edge_list[nHard][i];
		if (inQueue[u] == false)
		{
		    queue[open++] = u;
		    inQueue[u] = true;
		}
	}
	
	if (open == nCount)
	{
		printf("YES\n");
		if (dup)
			--nCount;
		printf("%d", queue[0]);
		for (int i = 1; i < nCount; ++i)
		    printf(" %d", queue[i]);
		printf("\n");
	} else
//		printf("open = %d, NO\n", open);
		printf("NO\n");
}

int main()
{
	scanf("%d%d%d", &nCount, &nEasy, &nHard);
	
	init();
	
	for (int i = 0; i < nCount; ++i)
	{
		int nEdges;
		scanf("%d", &nEdges);
		
		int ep;
		
		while (nEdges --)
		{
			scanf("%d", &ep);
			edge_list[i].push_back(ep);
			edge_list[ep].push_back(i);
		}
	}
	
//	printf("NO\n");
	find_solution();
	
	return 0;
}
